#include "ui.hpp"

#include <graphics.h>
#include <math.h>

#define PI (3.1415926)

#define HP_ROBORT_HIGH (50)
#define HP_WIDTH (7)
#define HP_HALF_HEIGTH (30)

#define DEFAULT_GUN_LENGTH (27)

#define SENTRY_R (17)
#define HERO_HALF_LENGTH (25)
#define INFANTRY_R (20)
#define INFANTRY_ARC_R (23)
#define BASE_HALF_LENGTH (30)
#define BASE_HALE_WINDTH (20)
#define KUGEL_SPEED (30)  //子弹偏移量
#define UI_KEYBOARD (30)

void UI::UI_Start() {
  LPCSTR AB1 = "刘骢 尹德智 郭涵", AB2 = "用户1: W A S D  移动 H I 选择角色 ",
         AB3 = "用户2：↑↓←→ 移动 + - 选择角色", AB4 = "TAB 开始游戏";

  setcolor(RGB(0, 0xff, 0xff));
  setfont(50, 0, AB1);
  outtextxy(SCREEN_WIDTH * 0.35, SCREEN_HEIGHT * 0.6, AB1);
  setfont(50, 0, AB4);
  outtextxy(SCREEN_WIDTH * 0.4, SCREEN_HEIGHT * 0.8, AB4);
  setcolor(RGB(0xff, 0, 0));
  setfont(100, 0, AB2);
  outtextxy(SCREEN_WIDTH * 0.05, SCREEN_HEIGHT * 0.2, AB2);
  setcolor(RGB(0, 0, 0xff));
  setfont(100, 0, AB3);
  outtextxy(SCREEN_WIDTH * 0.05, SCREEN_HEIGHT * 0.4, AB3);
  setfont(15, 0, AB4);
}

void UI::UI_End(Config_Color_t color) {
  LPCSTR BC1 = "BLUE WIN", BC2 = "RED WIN";
  setfont(100, 0, BC1);
  setfont(100, 0, BC2);
  if (color == CONFIG_COLOR_BLUE) {
    setcolor(RGB(0xff, 0, 0));
    outtextxy(SCREEN_WIDTH * 0.05, SCREEN_HEIGHT * 0.2, BC1);
  } else if (color == CONFIG_COLOR_RED) {
    setcolor(RGB(0, 0, 0xff));
    outtextxy(SCREEN_WIDTH * 0.05, SCREEN_HEIGHT * 0.2, BC2);
  }
}

void UI::UI_Show(Config_Robot_Name_t robot, Config_Color_t color,
                 Address_t *address, Address_t *target, float angle,
                 float HP_Range) {
  switch (color) {
    case CONFIG_COLOR_RED:
      setfillcolor(RGB(0, 0, 0xff));
      break;
    case CONFIG_COLOR_BLUE:
      setfillcolor(RGB(0xff, 0, 0));
      break;
  }
  switch (robot) {
    case Base:
      fillrect(address->x - BASE_HALF_LENGTH, address->y - BASE_HALE_WINDTH,
               address->x + BASE_HALF_LENGTH, address->y + BASE_HALE_WINDTH);
      outtextxy(address->x - BASE_HALF_LENGTH * 0.5,
                address->y - BASE_HALE_WINDTH * 0.4, "BASE");
      bar(address->x - HP_HALF_HEIGTH,
          address->y - HP_ROBORT_HIGH * 0.8 - HP_WIDTH * 0.8,
          address->x - HP_HALF_HEIGTH + 2 * HP_HALF_HEIGTH * HP_Range,
          address->y - HP_ROBORT_HIGH * 0.8);
      break;
    case Hero:
      bar(address->x - HERO_HALF_LENGTH, address->y - HERO_HALF_LENGTH,
          address->x + HERO_HALF_LENGTH, address->y + HERO_HALF_LENGTH);
      line(address->x, address->y,
           (DEFAULT_GUN_LENGTH * 2 * cos(angle) + address->x),
           (DEFAULT_GUN_LENGTH * 2 * sin(-angle) + address->y));
      bar(address->x - HP_HALF_HEIGTH, address->y - HP_ROBORT_HIGH - HP_WIDTH,
          address->x - HP_HALF_HEIGTH + 2 * HP_HALF_HEIGTH * HP_Range,
          address->y - HP_ROBORT_HIGH);
      break;
    case Infantry:
      pieslice(address->x, address->y, angle / PI * 180, angle / PI * 180,
               INFANTRY_R);
      arc(address->x, address->y, angle / PI * 180 - 30, angle / PI * 180 + 30,
          INFANTRY_ARC_R);
      line(address->x, address->y,
           (DEFAULT_GUN_LENGTH * cos(angle) + address->x),
           (DEFAULT_GUN_LENGTH * sin(-angle) + address->y));
      bar(address->x - HP_HALF_HEIGTH, address->y - HP_ROBORT_HIGH - HP_WIDTH,
          address->x - HP_HALF_HEIGTH + 2 * HP_HALF_HEIGTH * HP_Range,
          address->y - HP_ROBORT_HIGH);
      break;
    case Sentry:
      pieslice(address->x, address->y, angle / PI * 180, angle / PI * 180,
               SENTRY_R);
      line(address->x, address->y,
           (DEFAULT_GUN_LENGTH * cos(angle) + address->x),
           (DEFAULT_GUN_LENGTH * sin(-angle) + address->y));
      bar(address->x - HP_HALF_HEIGTH, address->y - HP_ROBORT_HIGH - HP_WIDTH,
          address->x - HP_HALF_HEIGTH + 2 * HP_HALF_HEIGTH * HP_Range,
          address->y - HP_ROBORT_HIGH);
      break;
    default:
      break;
  }
  switch (color) {
    case CONFIG_COLOR_RED:
      setcolor(RGB(0, 0, 0xff));
      break;
    case CONFIG_COLOR_BLUE:
      setcolor(RGB(0xff, 0, 0));
      break;
  }
  line(address->x, address->y, target->x, target->y);
  setfillcolor(RGB(0xff, 0xff, 0xff));
  setcolor(RGB(0xff, 0xff, 0xff));
}

void UI::Bullet_Casing(Address_t *origin, Address_t *target,
                       int time) {  //创建子弹
  double middle_x, middle_y;
  double sin_xy, cos_xy;
  sin_xy = (target->y - origin->y) /
           sqrt((origin->x - target->x) * (origin->x - target->x) +
                (origin->y - target->y) * (origin->y - target->y));
  cos_xy = (target->x - origin->x) /
           sqrt((origin->x - target->x) * (origin->x - target->x) +
                (origin->y - target->y) * (origin->y - target->y));
  middle_x = origin->x + time * KUGEL_SPEED * cos_xy;
  middle_y = origin->y + time * KUGEL_SPEED * sin_xy;

  arcf(middle_x, middle_y, 0, 0, 5);
}

UI::UI() {
  initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
  setcolor(RGB(0xff, 0xff, 0xff));
  setfillcolor(RGB(0xff, 0xff, 0xff));
  setrendermode(RENDER_MANUAL);
}

void UI::Clear() { cleardevice(); }

void UI::Delay() { delay_fps(30); }

void UI::Test() {
  Address_t a, b;
  a.x = 100;
  a.y = 100;
  UI_Show(Infantry, CONFIG_COLOR_BLUE, &a, &b, 0, 1);
}
